#ifndef _BUOLA_MEDIA_SUPPORT_PULSE_CPULSELOOP_H_
#define _BUOLA_MEDIA_SUPPORT_PULSE_CPULSELOOP_H_

#include <pulse/thread-mainloop.h>

namespace buola { namespace media { namespace pulse {

class CPulseContext;

class CPulseLoop
{
private:
    CPulseLoop();
    ~CPulseLoop();

    void Start();
    void Stop();

public:
    void Lock()     {   pa_threaded_mainloop_lock(mLoop);   }
    void Unlock()   {   pa_threaded_mainloop_unlock(mLoop); }

    void Signal(bool pWait=false)   {   pa_threaded_mainloop_signal(mLoop,pWait);   }
    void Wait()     {   pa_threaded_mainloop_wait(mLoop);   }
    void Accept()   {   pa_threaded_mainloop_accept(mLoop); }

    CPulseContext &GetDefaultContext();

private:
    pa_threaded_mainloop *mLoop;

    CPulseContext *mDefaultContext;

    friend class CPulseContext;
    friend CPulseLoop &get_default_loop();
};

CPulseLoop &get_default_loop();

inline CPulseContext &get_default_context()
{
    return get_default_loop().GetDefaultContext();
}

class CPulseLock
{
public:
    CPulseLock(CPulseLoop &pLoop=get_default_loop())
        :   mLoop(pLoop)
    {
        mLoop.Lock();
    }

    CPulseLock(CPulseLoop *pLoop)
        :   mLoop(*pLoop)
    {
        mLoop.Lock();
    }

    ~CPulseLock()
    {
        mLoop.Unlock();
    }

    void Wait()
    {
        mLoop.Wait();
    }

private:
    CPulseLoop &mLoop;
};

/*namespace pulse*/ } /*namespace media*/ } /*namespace buola*/ }

#endif /* __BLACKBOX_CPULSELOOP_H__ */
